package edu.siu.math.egut.main;

import java.io.IOException;
import java.util.Scanner;
import java.util.regex.Pattern;

import edu.siu.math.egut.io.BadLiECommandException;
import edu.siu.math.egut.io.LiE;
import edu.siu.math.egut.io.OutputPref;
import edu.siu.math.egut.local.Domain;
import edu.siu.math.egut.local.SectionIntegral;
import edu.siu.math.egut.local.UncomputableJacobianException;
import edu.siu.math.egut.util.ActionFailureException;
import edu.siu.math.egut.util.Algorithms;
import edu.siu.math.egut.util.BadSubstitutionException;
import edu.siu.math.egut.util.Group;
import edu.siu.math.egut.util.NotARootException;
import edu.siu.math.egut.util.Parabolic;
import edu.siu.math.egut.util.Polynomial;
import edu.siu.math.egut.util.PolynomialReadException;
import edu.siu.math.egut.util.Sunipotent;
import edu.siu.math.egut.util.Unipotent;
import edu.siu.math.egut.util.WeylWord;
import edu.siu.math.egut.util.WeylWordReadException;

public class Driver {

    /**
     * @param args
     * @throws NotARootException 
     * @throws PolynomialReadException 
     * @throws ActionFailureException 
     * @throws BadSubstitutionException 
     * @throws IOException 
     * @throws BadLiECommandException 
     * @throws WeylWordReadException 
     * @throws UncomputableJacobianException 
     */
    public static void main(String[] args) throws NotARootException, PolynomialReadException, BadSubstitutionException, ActionFailureException, IOException, BadLiECommandException, WeylWordReadException, UncomputableJacobianException {
	int[][] deltaRoots = {{0,1,0,0,0,0,0,0},{0,1,0,1,0,0,0,0},{0,1,0,1,1,0,0,0},{0,1,0,1,1,1,0,0},{0,1,0,1,1,1,1,0},{0,1,0,1,1,1,1,1},{0,1,1,1,0,0,0,0},{0,1,1,1,1,0,0,0},{0,1,1,1,1,1,0,0},{0,1,1,1,1,1,1,0},{0,1,1,1,1,1,1,1},{0,1,1,2,1,0,0,0},{0,1,1,2,1,1,0,0},{0,1,1,2,1,1,1,0},{0,1,1,2,1,1,1,1},{0,1,1,2,2,1,0,0},{0,1,1,2,2,1,1,0},{0,1,1,2,2,1,1,1},{0,1,1,2,2,2,1,0},{0,1,1,2,2,2,1,1},{0,1,1,2,2,2,2,1}};
	int[][] uRoots = {{1,0,0,0,0,0,0,0},{1,0,1,0,0,0,0,0},{1,0,1,1,0,0,0,0},{1,1,1,1,0,0,0,0},{1,0,1,1,1,0,0,0},{1,1,1,1,1,0,0,0},{1,0,1,1,1,1,0,0},{1,1,1,2,1,0,0,0},{1,1,1,1,1,1,0,0},{1,0,1,1,1,1,1,0},{1,1,2,2,1,0,0,0},{1,1,1,2,1,1,0,0},{1,1,1,1,1,1,1,0},{1,0,1,1,1,1,1,1},{1,1,2,2,1,1,0,0},{1,1,1,2,2,1,0,0},{1,1,1,2,1,1,1,0},{1,1,1,1,1,1,1,1},{1,1,2,2,2,1,0,0},{1,1,2,2,1,1,1,0},{1,1,1,2,2,1,1,0},{1,1,1,2,1,1,1,1},{1,1,2,3,2,1,0,0},{1,1,2,2,2,1,1,0},{1,1,2,2,1,1,1,1},{1,1,1,2,2,2,1,0},{1,1,1,2,2,1,1,1},{1,2,2,3,2,1,0,0},{1,1,2,3,2,1,1,0},{1,1,2,2,2,2,1,0},{1,1,2,2,2,1,1,1},{1,1,1,2,2,2,1,1},{1,2,2,3,2,1,1,0},{1,1,2,3,2,2,1,0},{1,1,2,3,2,1,1,1},{1,1,2,2,2,2,1,1},{1,1,1,2,2,2,2,1},{1,2,2,3,2,2,1,0},{1,2,2,3,2,1,1,1},{1,1,2,3,3,2,1,0},{1,1,2,3,2,2,1,1},{1,1,2,2,2,2,2,1},{1,2,2,3,3,2,1,0},{1,2,2,3,2,2,1,1},{1,1,2,3,3,2,1,1},{1,1,2,3,2,2,2,1},{1,2,2,4,3,2,1,0},{1,2,2,3,3,2,1,1},{1,2,2,3,2,2,2,1},{1,1,2,3,3,2,2,1},{1,2,3,4,3,2,1,0},{1,2,2,4,3,2,1,1},{1,2,2,3,3,2,2,1},{1,1,2,3,3,3,2,1},{2,2,3,4,3,2,1,0},{1,2,3,4,3,2,1,1},{1,2,2,4,3,2,2,1},{1,2,2,3,3,3,2,1},{2,2,3,4,3,2,1,1},{1,2,3,4,3,2,2,1},{1,2,2,4,3,3,2,1},{2,2,3,4,3,2,2,1},{1,2,3,4,3,3,2,1},{1,2,2,4,4,3,2,1},{2,2,3,4,3,3,2,1},{1,2,3,4,4,3,2,1},{2,2,3,4,4,3,2,1},{1,2,3,5,4,3,2,1},{2,2,3,5,4,3,2,1},{1,3,3,5,4,3,2,1},{2,3,3,5,4,3,2,1},{2,2,4,5,4,3,2,1},{2,3,4,5,4,3,2,1},{2,3,4,6,4,3,2,1},{2,3,4,6,5,3,2,1},{2,3,4,6,5,4,2,1},{2,3,4,6,5,4,3,1},{2,3,4,6,5,4,3,2}};
	String w0String="2";
	Pattern digits = Pattern.compile("\\d+");
	String wString = "878678567845678345678245678345672456345243";
	Unipotent delta = new Unipotent(deltaRoots, "d");
	Unipotent u = new Unipotent( uRoots, "u");
	Polynomial ell = Polynomial.read("u_{11221111}+u_{11122111}+u_{12232210}+u_{11233210}");
	int[] spec = {2};
	int[] alpha2 = {0,1,0,0,0,0,0,0};
	
	LiE lie = new LiE();
	
	lie.exec("setdefault E8", OutputPref.ERR);
	int[][] m = edu.siu.math.egut.io.Algorithms.readLiEMatrix(
		lie.exec("W_orbit(rho(D7),D7)", OutputPref.HIDE));
	
//	Domain d = new Domain(u.getAllVariables());
	Group g = Group.E8;
	WeylWord w =WeylWord.read(wString,g);
//	Parabolic p = new Parabolic(g, 1, spec);
//	
//	Sunipotent s = Sunipotent.create(deltaRoots[0], "d");
//	
//	u.actBy(s);
//	
//	Unipotent u1 = Unipotent.multiply(u, u);
//	
//	SectionIntegral si = new SectionIntegral(d, g, w, p,
//		    u1, ell,ell,ell);
//	
	long start;
	long diff;
	long sum1=0;
	long sum2=0;
//	Scanner scanner = new Scanner(System.in);
//	
//	System.out.println(si.toString(OutputStyle.SCREEN));
//	scanner.next();
//	si.makeChangesOfVariable();
//	scanner.next();
//	System.out.println(si.toString(OutputStyle.SCREEN));
	
	System.out.println(ell);
	System.out.println(Algorithms.action_1(w , ell, u));
	System.out.println(Algorithms.action_2(w , ell, u,g));
	
	
	
	Polynomial p1;
	Polynomial p2;
	
	for (int i = 1; i < m.length; i++) {
	    
	    System.out.println(
		    "noCom(word_translate(W_word("+
		    edu.siu.math.egut.io.Algorithms.tupleToString(m[i])
		    +", D7),m2gDict([1])))");
	    w= WeylWord.read( lie.exec(
		    "noCom(word_translate(W_word("+
		    edu.siu.math.egut.io.Algorithms.tupleToString(m[i])
		    +", D7),m2gDict([1])))", 
		    OutputPref.SHOW),g);
	    
	    start = System.nanoTime();
		p1= Algorithms.action_1(w , ell, u);
		diff=System.nanoTime() - start;
		sum1 += diff;
		System.out.println(diff);
		start = System.nanoTime();
		p2 = Algorithms.action_2(w , ell, u,g);
		diff=System.nanoTime() - start;
		sum2 += diff;
		System.out.println(diff);
		
		if(! p1.equals(p2)){
		    System.out.println("i="+i);
		    System.out.println(p1);
		    System.out.println(p2);
		    i=m.length;
		}
	    
	    
	    
	   
	}
	System.out.println(sum1/m.length);
	System.out.println(sum2/m.length);
	
	
//	
	
	System.out.println("Process complete.");
   }

}
